package edu.ynu.se.xiecheng.achitectureclass.demo.service;

import edu.ynu.se.xiecheng.achitectureclass.common.service.LogicService;
import edu.ynu.se.xiecheng.achitectureclass.demo.config.HttpClientConfig;
import edu.ynu.se.xiecheng.achitectureclass.demo.dao.SensorDataDao;
import edu.ynu.se.xiecheng.achitectureclass.demo.entity.data.SensorData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SensorDataService extends LogicService<SensorDataDao, SensorData, Long> {
    public SensorDataService(@Autowired SensorDataDao dao) {
        super(dao);
    }

    private static final String CLIENT_ID = "68db2e8bda8d47b5b5db7eaf71c7dcdd";
    private static final String CLIENT_SECRET = "76dc724c95004acab25482d344dab407";
    private static final String FBOX_LOGIN_URL = "https://fbox360.com/idserver/core/connect/token";

    private String accessToken;
    private long expiresAt;
    @Autowired
    private HttpClientConfig httpClientConfig;

    public SensorData findLastSensorDataByDeviceId(Long deviceId) {
        List<SensorData> sensorDatas = getDAO().findAllByDeviceIdOrderByCreateTimeAsc(deviceId);
        if(sensorDatas.isEmpty()) {
            return null;
        }
        return sensorDatas.get(0);
    }
    public List<SensorData> findLastNumbersSensorDataByDeviceId(Long deviceId, Integer number) {
        List<SensorData> sensorDatas = getDAO().findAllByDeviceIdOrderByCreateTimeAsc(deviceId);
        if(sensorDatas.isEmpty()) {
            return null;
        }
        return sensorDatas.subList(sensorDatas.size() - number, sensorDatas.size());
    }

    public Map<String, String> getSensorToken(){

        if (accessToken != null && System.currentTimeMillis() < expiresAt) {
            Map<String, String> tokenMap = new HashMap<>();
            tokenMap.put("access_token", accessToken);

            return tokenMap;
        }

        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("scope", "fbox");
        params.add("client_id", CLIENT_ID);
        params.add("client_secret", CLIENT_SECRET);
        params.add("grant_type", "client_credentials");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);

        try {
            ResponseEntity<Map> response = httpClientConfig.restTemplate().postForEntity(FBOX_LOGIN_URL, request, Map.class);
            if (response.getStatusCode().is2xxSuccessful()) {
                Map<String, Object> responseBody = response.getBody();
                accessToken = (String) responseBody.get("access_token");
                expiresAt = System.currentTimeMillis() + (int)responseBody.get("expires_in") * 1000;
                Map<String, String> tokenMap = new HashMap<>();
                tokenMap.put("access_token", accessToken);

                return tokenMap;
            } else {
                throw new RuntimeException("Failed to obtain access token: " + response.getStatusCode());
            }
        } catch (Exception e) {
            throw new RuntimeException("Error obtaining access token: " + e.getMessage());
        }
    }
}